using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Globalization;
using System.Threading;

namespace DataAccess
{
    public class IntegrityCalculator
    {
        CultureInfo currentCulture;
        CultureInfo currentUICulture;
        bool started = false;

        public void Start()
        {
            currentCulture = Thread.CurrentThread.CurrentCulture;
            currentUICulture = Thread.CurrentThread.CurrentUICulture;
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
        }

        public void End()
        {
            if (started)
            {
                Thread.CurrentThread.CurrentCulture = currentCulture;
                Thread.CurrentThread.CurrentUICulture = currentUICulture;
            }
        }

        public int CalculateHash(DataRow row)
        {
            DataColumnCollection columns = row.Table.Columns;
            int hash = 0;

            if (columns.Contains(Common.DataConstants.RowHashColumn))
            {
                if (!started) this.Start();

                foreach (DataColumn col in columns)
                {
                    if (col.ColumnName != Common.DataConstants.RowHashColumn)
                    {
                        hash = hash | CalculateScalarHash(row[col]);
                    }
                }
            }

            return hash;
        }

        public void UpdateHash(DataRow row)
        {
            DataColumnCollection columns = row.Table.Columns;

            if (columns.Contains(Common.DataConstants.RowHashColumn))
            {
                int hash = CalculateHash(row);
                row[Common.DataConstants.RowHashColumn] = hash;
            }
        }

        private int CalculateScalarHash(object value)
        {
            Byte hash = 0;
            System.Text.Encoding ascii = System.Text.Encoding.ASCII;
            Byte[] encodedBytes = ascii.GetBytes(value.ToString());
            foreach (Byte b in encodedBytes)
            {
                hash = (byte)(hash | (b | ((byte)7)));
            }
            return Convert.ToInt32(hash);
        }

        ~IntegrityCalculator()
        {
            End();
        }
    }
}
